//-----------------------------------------------------------------------------
//	File: mgui_2d.c
//	Author: xialing
//		2d of mgui
//-----------------------------------------------------------------------------

#include "mgui_2d.h"

//-----------------------------------------------------------------------------
//	mgui_draw_hline - draw a horizontal line
//		@x0: start x position
//		@y: start y position
//		@x1: end x position
//		@c: 0 or 1
//-----------------------------------------------------------------------------
void mgui_draw_hline(uint16_t x0, uint16_t y, uint16_t x1, uint8_t c)
{
	for (; x0 <= x1; x0++) {
		mgui_draw_pixel(x0, y, c ^ mgui_conf->invc);
	}
}

//-----------------------------------------------------------------------------
//	mgui_draw_vline - draw a vertical line
//		@x: start x position
//		@y0: start y position
//		@y1: end y position
//		@c: 0 or 1
//-----------------------------------------------------------------------------
void mgui_draw_vline(uint16_t x, uint16_t y0, uint16_t y1, uint8_t c)
{
	for (; y0 <= y1; y0++) {
		mgui_draw_pixel(x, y0, c ^ mgui_conf->invc);
	}
}

//-----------------------------------------------------------------------------
//	mgui_draw_rect - draw a rectangle
//		@x0: start x position
//		@y0: start y position
//		@x1: diagonal x position
//		@y1: diagonal y position
//		@c: 0 or 1
//-----------------------------------------------------------------------------
void mgui_draw_rect(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint8_t c)
{
	mgui_draw_hline(x0, y0, x1, c);
	mgui_draw_hline(x0, y1, x1, c);
	mgui_draw_vline(x0, y0, y1, c);
	mgui_draw_vline(x1, y0, y1, c);
}

//-----------------------------------------------------------------------------
//	mgui_draw_fullrect - draw a full rectangle
//		@x0: start x position
//		@y0: start y position
//		@x1: diagonal x position
//		@y1: diagonal y position
//		@c: 0 or 1
//-----------------------------------------------------------------------------
void mgui_draw_fullrect(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint8_t c)
{
	uint16_t i;

	for (; y0<=y1; y0++) {
		for (i=x0; i<=x1; i++) {
			mgui_draw_pixel(i, y0, c ^ mgui_conf->invc);
		}
	}
}

//-----------------------------------------------------------------------------
//	mgui_clear_area - clear area
//		@x0: start x position
//		@y0: start y position
//		@x1: diagonal x position
//		@y1: diagonal y position
//-----------------------------------------------------------------------------
void mgui_clear_area(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1)
{
	uint16_t i;

	for (; y0<=y1; y0++) {
		for (i=x0; i<=x1; i++) {
			mgui_draw_pixel(i, y0, 0 ^ mgui_conf->invc);
		}
	}
}

//-----------------------------------------------------------------------------
//	mgui_draw_line - draw a line
//		@x0: start x position
//		@y0: start y position
//		@x1: end x position
//		@y1: end y position
//		@c: 0 or 1
//-----------------------------------------------------------------------------
void mgui_draw_line(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint8_t c)
{
	uint16_t i, dx, dy;
	int8_t ux, uy, e;

	if (x1 > x0) {
		dx = x1 - x0;
		ux = 1;
	} else {
		dx = x0 - x1;
		ux = -1;
	}

	if (y1 > y0) {
		dy = y1 - y0;
		uy = 1;
	} else {
		dy = y0 - y1;
		uy = -1;
	}

	if (dx > dy) {
		e = dx >> 1;
		for (i = 0; i <= dx; i++) {
			mgui_draw_pixel(x0, y0, c ^ mgui_conf->invc);
			x0 += ux;
			e += dy;
			if (e >= dx) {
				y0 += uy;
				e -= dx;
			}
		}
	} else {
		e = dy >> 1;
		for (i = 0; i <= dy; i++) {
			mgui_draw_pixel(x0, y0, c ^ mgui_conf->invc);
			y0 += uy;
			e += dx;
			if (e >= dy) {
				x0 += ux;
				e -= dy;
			}
		}
	}
}

//-----------------------------------------------------------------------------
//	mgui_draw_circle - draw a circle
//		@x: the centre of a circle x position
//		@y: the centre of a circle y position
//		@r: the radius of a circle
//		@c: 0 or 1
//-----------------------------------------------------------------------------
void mgui_draw_circle(uint16_t x, uint16_t y, uint16_t r, uint8_t c)
{
	uint32_t cx = 0;
	uint32_t cy = r;
	int16_t d = 3 - (r << 1);
	
	while (cx <= cy) {
		mgui_draw_pixel(x + cx, y + cy, c ^ mgui_conf->invc);
		mgui_draw_pixel(x + cx, y - cy, c ^ mgui_conf->invc);
		mgui_draw_pixel(x - cx, y + cy, c ^ mgui_conf->invc);
		mgui_draw_pixel(x - cx, y - cy, c ^ mgui_conf->invc);
		mgui_draw_pixel(x + cy, y + cx, c ^ mgui_conf->invc);
		mgui_draw_pixel(x + cy, y - cx, c ^ mgui_conf->invc);
		mgui_draw_pixel(x - cy, y + cx, c ^ mgui_conf->invc);
		mgui_draw_pixel(x - cy, y - cx, c ^ mgui_conf->invc);
		if (d < 0) {
			d += (cx << 2) + 6;
		} else {
			d += ((cx - cy) << 2) + 10;
			cy--;
		}
		cx++;
	}
}

//-----------------------------------------------------------------------------
//	mgui_draw_bmp - mgui draw a bmp
//		@b: bmp
//-----------------------------------------------------------------------------
void mgui_draw_bmp(uint8_t *b, uint16_t x, uint16_t y)
{
	uint16_t i, j, w, h;

    w = (b[3] << 8) | b[2];
    h = (b[5] << 8) | b[4];

	b += 6;
	for (j=0; j<h; j++) {
		for (i=0; i<w; i++) {
			if (b[i >> 3] & (0x80 >> (i & 7))) {
				mgui_draw_pixel(x + i, y + j, 1 ^ mgui_conf->invc);
			} else {
				mgui_draw_pixel(x + i, y + j, 0 ^ mgui_conf->invc);
			}
		}
		b += (i + 7) >> 3;
	}
}

